#!/usr/bin/python2.5


import pygame, pygame.font, sys, time, os
from pygame.locals import *

sys.path.append("../")
import game
pygame.init()



#TODO: for some reason, nothing ends up rendering, even though the loop is called.



class Window(object):
    """
    A graphical window, in which all else is displayed.
        Initialized with a GameScreen object.
    """
    def __init__(self, game, gamescreen, path):
        self.filepath = path
        self.game = game
        self.gamescreen = gamescreen
        self.height = self.gamescreen.dimensions[1] + 15
        self.width = self.gamescreen.dimensions[0]
        print self.height, self.width
        self.elements = self.load_objects( self.gamescreen.startobjects )
        #clickable area
        self.legal_height = self.height - 15
        self.legal_width = self.width
        
        self.background = pygame.Surface([self.width, self.height])
        #make me a display
        try:
            # Have to do this here or we get errors the 
            # second time you open a window
            pygame.font.init()
        except: pass

        pygame.display.set_mode([self.width, self.height])
        pygame.display.set_caption('Game-Baker GameScreen Editor')
        self.screen = pygame.display.get_surface()
        self.info_bar = InfoBar(self.width, self.legal_height)
        #this represents the currently clicked on item
        self.selected = None
    
    def load_objects(self, objects):
        """Wraps each gameobject in the Element class"""
        wrapped = []
        for obj in objects:
            wrapped.append(Element(obj,main_wnd = self))
        return wrapped

    def save_layout(self):
        """Returns the updated list of startobjects"""
        elements = []
        for elem in self.elements:
            elements.append(elem.save())
        return elements
    
    def render(self):
        """Renders all objects in self.elements (and currently selected element)"""
        self.screen.blit(self.background, [0,0])
        for elem in self.elements:
            self.screen.blit(elem.render(), [elem.x, elem.y])
        self.screen.blit(self.info_bar.render(), [self.info_bar.x, self.info_bar.y])
        #render self.selected:
        if self.selected is not None:
            self.screen.blit(self.selected.render(), [self.selected.x, self.selected.y])
    
    def update(self):
        self.render()
        pygame.display.flip()
        
        
    def add_element(self, element):
        self.elements.append(element)


    def get_element_at_point(self,x,y):
        for element in self.elements:
            if element.check_point_collision(x,y):
                return element
        return None

        
    def run(self):
        while True:
            self.update()
            coords = pygame.mouse.get_pos()
            
            if self.selected is not None:
                #follow mouse
                self.selected.x = coords[0]
                self.selected.y = coords[1]
            
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.display.quit()
                    pygame.quit()
                    return self.save_layout()
                if event.type == MOUSEBUTTONUP and event.button == 1:
                    if self.legal_coords(coords):
                        if self.selected is None:
			                print coords
			                self.selected = self.get_element_at_point(coords[0], coords[1])
                        else:
                            self.selected = None


    def legal_coords(self, coords):
        if coords[0] < self.legal_width and coords[0] > 0 and coords[1] < self.legal_height and coords[1] > 0:
           	return True
        else:
			return False
			
        

class Element(object):
    """A wrapper for gameobjects to be placed in the Window class."""
    def __init__(self, gameobject, main_wnd):
        self.backup_go = gameobject
        
        self.x = gameobject.x
        self.y = gameobject.y

        game = main_wnd.game
        filepath = main_wnd.filepath
        
        if gameobject.sprite is None:
            #default height and width. Should be changed at some point.
            self.height = 30 
            self.width = 30
            self.image = pygame.Surface([self.width, self.height])
            self.image.fill(111)
        else:
            sprite = game.sprites[gameobject.sprite]
            spriteimage = sprite.imagefiles[0]
            imagepath = os.path.join(filepath,spriteimage["filename"])

            print imagepath

            self.image = pygame.image.load(imagepath)
            try:
                # I'm getting an exception here because the video mode hasn't been set
                # (TimWintle)
                self.image = self.image.convert()
            except: 
                print "exception - video mode not set"

            self.width = spriteimage["bottomright"][0] - spriteimage["topleft"][0]
            self.height = spriteimage["bottomright"][1] - spriteimage["topleft"][1]
            
        
    def move(self, x, y):
    	self.x = x
        self.y = y
        
    def check_point_collision(self,x,y):
        """Checks if a point is within the object's collision area"""
        return self.x <= x and self.y <= y and self.width + self.x >= x and self.height + self.y >= y
	
    def set_color(self, color):
        self.image.fill(color)
        
    def render(self):
        """Returns the graphical representation of the element"""
        return self.image
        
    def save(self):
        """Returns the updated gameobject"""
        self.backup_go.x = self.x
        self.backup_go.y = self.y
        return self.backup_go

        
class InfoBar(object):
    """A class which displays useful info at the bottom of the window."""
    def __init__(self, width, pixels_from_top):
        self.x = 0
        self.y = pixels_from_top
        self.height = 15
        self.width = width
        self.background = pygame.Surface([self.width, self.height])
        self.image = self.background.copy()
        self.text = "GB-Editor"
        self.color = (0,255,0)
        self.background.fill(200)
        self.background_color = (0,0,255)
        self.menu_font = pygame.font.Font(None, 22)
        rendered_text = self.menu_font.render(self.text, True, self.color, self.background_color)
        self.background.blit(rendered_text, [0,0])
    
    def render(self):
        """Returns the graphical representation of the element"""
        self.update()
        return self.image
        
    def update(self):
        """Refreshes the information on the info-bar."""
        self.image = self.background.copy()
        text = self.menu_font.render("Cursor: " + str(pygame.mouse.get_pos()), True, self.color, self.background_color)
        self.image.blit(text, [100,0])


if __name__ == "__main__":
    test = game.GameScreen((800,600))
    test.startobjects.append(game.GameObject())
    w = Window(test)
    w.run()    

